// SPDX-FileCopyrightText: Adam Evyčędo
//
// SPDX-License-Identifier: GPL-3.0-or-later

package xyz.apiote.bimba.czwek.settings.feeds

import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.launch
import xyz.apiote.bimba.czwek.data.exceptions.BimbaException
import xyz.apiote.bimba.czwek.data.settings.SettingsRepository
import xyz.apiote.bimba.czwek.data.sources.Server
import xyz.apiote.bimba.czwek.repo.FeedInfo
import xyz.apiote.bimba.czwek.repo.joinFeeds

class FeedsViewModel : ViewModel() {
	private val _settings = MutableLiveData<FeedsSettings>()
	val settings: LiveData<FeedsSettings> = _settings

	private val mutableFeeds = MutableStateFlow(mapOf<String, FeedInfo>())
	val feeds: StateFlow<Map<String, FeedInfo>> = mutableFeeds

	private var notifyRecycler = true

	private val errors: MutableSet<BimbaException> = mutableSetOf()

	var finishedGettingFeeds = false
		private set

	lateinit var server: Server

	fun consumeErrors(): List<BimbaException> {
		val errors = this.errors.map { it }
		this.errors.clear()
		return errors
	}

	fun consumeNotifyRecycler(): Boolean {
		val value = notifyRecycler
		notifyRecycler = true
		return value
	}

	fun getServer(context: Context) {
		server = Server.get(context)
		viewModelScope.launch {
			server.getTraffic(context)
			migrateFeedsSettings(context)
			loadSettings(context)
			loadFeeds(context)
		}
	}

	private fun loadSettings(context: Context) {
		_settings.value = SettingsRepository().getAllFeeds(context)
	}

	fun setSettings(feedID: String, feedSettings: FeedSettings) {
		val feedsSettings = _settings.value ?: FeedsSettings.EMPTY
		_settings.value = feedsSettings.with(feedID, feedSettings)
	}

	fun setEnabled(feedID: String, enabled: Boolean) {
		val feedsSettings = _settings.value ?: FeedsSettings.EMPTY
		notifyRecycler = false
		_settings.value = feedsSettings.setEnabled(feedID, enabled)
	}

	private suspend fun loadFeeds(context: Context) {
		finishedGettingFeeds = false
		mutableFeeds.value = emptyMap<String, FeedInfo>()
		val repo = SettingsRepository()

		repo.getFeedInfos(context)
			.onCompletion {
				finishedGettingFeeds = true
			}
			.collect { feedInfoFlowItem ->
				when (feedInfoFlowItem) {
					is FeedInfo -> {
						joinFeeds(mutableFeeds.value, mapOf(feedInfoFlowItem.id to feedInfoFlowItem)).let {
							mutableFeeds.value = it

							repo.saveFeedInfos(it, context)
						}
					}

					is BimbaException -> {
						errors.add(feedInfoFlowItem)
					}
				}
			}
	}
}
